﻿using System;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;

namespace NeGroid.ChampionshipManager.Persistance
{
	internal class QueryHelper
	{
		public static MethodCallExpression GenerateMethodCall<TEntity>(IQueryable<TEntity> source, string methodName, String fieldName)
		{
			var type = typeof(TEntity);
			Type selectorResultType;
			var selector = GenerateSelector<TEntity>(fieldName, out selectorResultType);
			var resultExp = Expression.Call(typeof(Queryable), methodName,
											new[] { type, selectorResultType },
											source.Expression, Expression.Quote(selector));
			return resultExp;
		}

		public static LambdaExpression GenerateSelector<TEntity>(String propertyName, out Type resultType)
		{
			var parameter = Expression.Parameter(typeof(TEntity), "Entity");
			PropertyInfo property;
			Expression propertyAccess;
			if (propertyName.Contains('.'))
			{
				var childProperties = propertyName.Split('.');
				property = typeof(TEntity).GetProperty(childProperties[0]);
				propertyAccess = Expression.MakeMemberAccess(parameter, property);
				for (var i = 1; i < childProperties.Length; i++)
				{
					property = property.PropertyType.GetProperty(childProperties[i]);
					propertyAccess = Expression.MakeMemberAccess(propertyAccess, property);
				}
			}
			else
			{
				property = typeof(TEntity).GetProperty(propertyName);
				propertyAccess = Expression.MakeMemberAccess(parameter, property);
			}
			resultType = property.PropertyType;
			return Expression.Lambda(propertyAccess, parameter);
		}
	}
}
